package com.stox.dto;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import com.stox.indicator.Indicator;
import com.stox.util.StringUtil;

@SuppressWarnings("rawtypes")
public class IndicatorModel extends AbstractModel implements Cloneable{
	private static final long serialVersionUID = 1L;
	
	public static final Type INDICATOR_TYPE = new Type("Indicator");
	
	private final Object configuration;
	
	private final Indicator indicator;
	
	public IndicatorModel(Indicator indicator) {
		this(indicator, indicator.createDefaultConfiguration());
	}
	
	private IndicatorModel(Indicator indicator, Object configuration) {
		super(INDICATOR_TYPE);
		this.indicator = indicator;
		this.configuration = configuration;
		setName(StringUtil.splitCamelCase(indicator.getClass().getSimpleName()));
		setId(new Long(getName().hashCode()));
	}
	
	@Override
	protected IndicatorModel clone() throws CloneNotSupportedException {
		Object configuration = indicator.createDefaultConfiguration();
		try {
			BeanUtils.copyProperties(configuration, this.configuration);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new IndicatorModel(indicator, configuration);
	}

	public Indicator getIndicator() {
		return indicator;
	}
	
	private CustomToStringStyle customeToStringStyle = new CustomToStringStyle();
	
	@Override
	public String toString() {
		return getName() + ToStringBuilder.reflectionToString(configuration, customeToStringStyle);
	}
	
	public Object getConfiguration() {
		return configuration;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result
				+ ((configuration == null) ? 0 : configuration.hashCode());
		result = prime * result
				+ ((indicator == null) ? 0 : indicator.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		IndicatorModel other = (IndicatorModel) obj;
		if (configuration == null) {
			if (other.configuration != null)
				return false;
		} else if (!configuration.equals(other.configuration))
			return false;
		if (indicator == null) {
			if (other.indicator != null)
				return false;
		} else if (!indicator.equals(other.indicator))
			return false;
		return true;
	}

}

class CustomToStringStyle extends ToStringStyle{
	private static final long serialVersionUID = 1L;

	public CustomToStringStyle() {
		 super();
         this.setUseClassName(false);
         this.setUseIdentityHashCode(false);
	}
	
}